package com.raincat.tools.multimediapickertools;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.chad.library.adapter.base.listener.OnItemChildLongClickListener;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.chad.library.adapter.base.listener.OnItemLongClickListener;
import com.chad.library.adapter.base.module.LoadMoreModule;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.michaelflisar.dragselectrecyclerview.DragSelectTouchListener;
import com.raincat.tools.R;
import com.raincat.tools.multimediapickertools.utils.DropDownPopupWindow;
import com.raincat.tools.multimediapickertools.utils.EasyActionBar;
import com.raincat.tools.multimediapickertools.utils.GridSpaceItemDecoration;
import com.raincat.tools.multimediapickertools.utils.ImageCacheUtils;
import com.raincat.tools.multimediapickertools.utils.MultiMediaBucket;
import com.raincat.tools.multimediapickertools.utils.MultiMediaController;
import com.raincat.tools.multimediapickertools.utils.MultiMediaHelper;
import com.raincat.tools.multimediapickertools.utils.MultiMediaItem;
import com.raincat.tools.multimediapickertools.utils.TipsPopWindow;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <pre>
 *     author : RainCat
 *     org    : Shenzhen JingYu Network Technology Co., Ltd.
 *     e-mail : nining377@gmail.com
 *     time   : 2019/02/27
 *     desc   : 多媒体浏览器主页，请务必从PickerConfig.start()打开
 *     version: 1.0
 * </pre>
 */
public class PictureActivity extends AppCompatActivity {
    private static final int RESULT_TACK = 0x01;
    public static final int RESULT_CROP = 0x02;
    private static final int RESULT_CAMERA = 0x03;
    private static final int RESULT_VIDEO = 0x04;

    private Context context;

    private ProgressDialog dialog;

    private EasyActionBar easyActionBar;
    private ImageView iv_original;
    private TextView tv_original;
    private Button btn_sure;
    private RecyclerView recyclerView;
    private LinearLayout ll_bottom;

    private RecyclerViewAdapter recyclerViewAdapter;

    private List<MultiMediaBucket> imageBucketList;
    private int bucketIndex = 0;
    private String cameraPath = "";

    private DragSelectTouchListener dragSelectTouchListener;    //拖动选择控件
    private boolean isAddImg = true;    //拖动时是否为添加图片，true添加，false取消

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
        localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        if (!MultiMediaController.isInit)
            throw new IllegalStateException(getString(R.string.picker_init_error));
        setTheme(MultiMediaController.themeId);
        setContentView(R.layout.picker_activity_picture);

        context = this;

        initView();
        initData();
        listener();
    }

    private void initView() {
        easyActionBar = findViewById(R.id.easyActionBar);
        easyActionBar.setImmerseLayout();
        iv_original = findViewById(R.id.iv_original);
        tv_original = findViewById(R.id.tv_original);
        btn_sure = findViewById(R.id.btn_sure);
        recyclerView = findViewById(R.id.recyclerView);
        ll_bottom = findViewById(R.id.ll_bottom);

        if (MultiMediaController.mode == MultiMediaController.VIDEO)
            ll_bottom.setVisibility(View.GONE);
        else
            ll_bottom.setVisibility(View.VISIBLE);

        recyclerViewAdapter = new RecyclerViewAdapter(context, new ArrayList<MultiMediaItem>());
        GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 3);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerView.addItemDecoration(new GridSpaceItemDecoration(2, 3));
        recyclerView.setItemViewCacheSize(30);
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(recyclerViewAdapter);
        ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        if (!preferences.getBoolean("tips", false)) {
            easyActionBar.post(new Runnable() {
                @Override
                public void run() {
                    new TipsPopWindow(context, easyActionBar);
                }
            });
        }
    }

    private void initData() {
        changeStatusBarTextColor(MultiMediaController.blackStatusBar);
        dialog = ProgressDialog.show(context, null, getString(R.string.picker_now_loading_please_wait));
        if (MultiMediaController.mode < 3) {
            MultiMediaHelper.getInstance(context).getMultiMediaBucketList(context, MultiMediaController.mode == MultiMediaController.MIX, MultiMediaController.showGif, new MultiMediaHelper.onBucketListGetListener() {
                @Override
                public void onFinish(List<MultiMediaBucket> bucketList) {
                    imageBucketList = bucketList;
                    setData(true);
                }
            });
        } else {
            imageBucketList = new ArrayList<>();
            imageBucketList.add(MultiMediaHelper.getInstance(context).getVideosBucketList(context));
            setData(true);
        }
    }

    private void listener() {
        easyActionBar.setOnLeftLayoutClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finishActivity();
            }
        });
        iv_original.setOnClickListener(new View.OnClickListener() {
            public void onClick(View paramAnonymousView) {
                MultiMediaController.isOriginal = !MultiMediaController.isOriginal;
                setOriginal();
            }
        });
        tv_original.setOnClickListener(new View.OnClickListener() {
            public void onClick(View paramAnonymousView) {
                MultiMediaController.isOriginal = !MultiMediaController.isOriginal;
                setOriginal();
            }
        });
        btn_sure.setOnClickListener(new View.OnClickListener() {
            public void onClick(View paramAnonymousView) {
                if (MultiMediaController.mode == MultiMediaController.CROP) {
                    startActivityForResult(new Intent(context, CropActivity.class), RESULT_CROP);
                } else {
                    MultiMediaController.getMultiMediaList(context);
                }
            }
        });
        easyActionBar.setOnTitleClickListener(new View.OnClickListener() {
            public void onClick(View paramAnonymousView) {
                TypedValue typedValue = new TypedValue();
                getTheme().resolveAttribute(R.attr.picker_actionBar_titleIconUp, typedValue, true);
                easyActionBar.setTitleRes(typedValue.resourceId);

                new DropDownPopupWindow(context, easyActionBar, bucketIndex, imageBucketList, new DropDownPopupWindow.OnListItemClickListener() {
                    public void onClick(int index) {
                        TypedValue typedValue = new TypedValue();
                        context.getTheme().resolveAttribute(R.attr.picker_actionBar_titleIconDown, typedValue, true);
                        easyActionBar.setTitleRes(typedValue.resourceId);
                        if (index != -1) {
                            bucketIndex = index;
                            if (MultiMediaController.mode == MultiMediaController.MIX) {
                                setData(bucketIndex == 0 || bucketIndex == 1);
                                if (bucketIndex == 1)
                                    ll_bottom.setVisibility(View.GONE);
                                else
                                    ll_bottom.setVisibility(View.VISIBLE);
                            } else {
                                setData(bucketIndex == 0);
                                if (MultiMediaController.mode == MultiMediaController.VIDEO)
                                    ll_bottom.setVisibility(View.GONE);
                            }
                        }
                    }
                });
            }
        });
        recyclerViewAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
                Intent intent;
                boolean cameraState = imageBucketList.get(bucketIndex).multiMediaItemList.get(0).path.equals(MultiMediaItem.CAMERA);

                if (bucketIndex == 0 && MultiMediaController.mode != MultiMediaController.VIDEO && position == 0 && cameraState) {
                    takePhotoByCamera();
                    return;
                } else if (bucketIndex == 0 && MultiMediaController.mode == MultiMediaController.VIDEO && position == 0 && cameraState) {
                    takeVideoByCamera();
                    return;
                } else if (bucketIndex == 1 && MultiMediaController.mode == MultiMediaController.MIX && position == 0 && cameraState) {
                    takeVideoByCamera();
                    return;
                } else if (imageBucketList.get(bucketIndex).multiMediaItemList.get(0).mimeType.equals("image"))
                    intent = new Intent(context, PicturesBrowseActivity.class);
                else
                    intent = new Intent(context, VideoBrowseActivity.class);

                intent.putExtra("CheckIndex", cameraState ? position - 1 : position);
                intent.putExtra("BucketIndex", bucketIndex);
                startActivityForResult(intent, RESULT_TACK);
            }
        });
        recyclerViewAdapter.addChildClickViewIds(R.id.tv_check);
        recyclerViewAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
            @Override
            public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
                MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(position));
                setCount();
                notifyDataSetChanged();
            }
        });
        recyclerViewAdapter.addChildLongClickViewIds(R.id.tv_check);
        recyclerViewAdapter.setOnItemChildLongClickListener(new OnItemChildLongClickListener() {
            @Override
            public boolean onItemChildLongClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
                isAddImg = MultiMediaController.multiMediaItemMap.get(imageBucketList.get(bucketIndex).multiMediaItemList.get(position).path) == null;
                MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(position));
                dragSelectTouchListener.startDragSelection(position);
                notifyDataSetChanged();
                setCount();
                return true;
            }
        });
        recyclerViewAdapter.setOnItemLongClickListener(new OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
                isAddImg = MultiMediaController.multiMediaItemMap.get(imageBucketList.get(bucketIndex).multiMediaItemList.get(position).path) == null;
                MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(position));
                dragSelectTouchListener.startDragSelection(position);
                notifyDataSetChanged();
                setCount();
                return true;
            }
        });
        dragSelectTouchListener = new DragSelectTouchListener().withSelectListener(new DragSelectTouchListener.OnDragSelectListener() {
            @Override
            public void onSelectChange(int start, int end, boolean isSelected) {
                for (int i = start; i <= end; i++) {
                    if (imageBucketList.get(bucketIndex).multiMediaItemList.get(i).path.equals(MultiMediaItem.CAMERA))
                        continue;
                    if (isAddImg) {
                        if (isSelected && MultiMediaController.multiMediaItemMap.get(imageBucketList.get(bucketIndex).multiMediaItemList.get(i).path) == null) {
                            MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(i));
                        } else if (!isSelected && MultiMediaController.multiMediaItemMap.get(imageBucketList.get(bucketIndex).multiMediaItemList.get(i).path) != null) {
                            MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(i));
                        }
                    } else {
                        if (isSelected && MultiMediaController.multiMediaItemMap.get(imageBucketList.get(bucketIndex).multiMediaItemList.get(i).path) != null) {
                            MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(i));
                        } else if (!isSelected && MultiMediaController.multiMediaItemMap.get(imageBucketList.get(bucketIndex).multiMediaItemList.get(i).path) == null) {
                            MultiMediaController.addOrRemoveMultiMediaItem(context, imageBucketList.get(bucketIndex).multiMediaItemList.get(i));
                        }
                    }
                }
                notifyDataSetChanged();
                setCount();
            }
        });
        recyclerView.addOnItemTouchListener(dragSelectTouchListener);
    }

    private void setCount() {
        if (btn_sure != null) {
            if (MultiMediaController.multiMediaItemMap.size() != 0) {
                btn_sure.setEnabled(true);
                btn_sure.setText(context.getResources().getString(R.string.picker_OK) + "(" + MultiMediaController.multiMediaItemMap.size() + "/" + MultiMediaController.maxCount + ")");
            } else {
                btn_sure.setEnabled(false);
                btn_sure.setText(context.getResources().getString(R.string.picker_OK));
            }
        }
        if (MultiMediaController.isOriginal) {
            tv_original.setText(context.getResources().getString(R.string.picker_original) + MultiMediaController.getImageSize());
        }
    }

    private void setOriginal() {
        if (!MultiMediaController.showOriginalOption) {
            iv_original.setVisibility(View.GONE);
            tv_original.setVisibility(View.INVISIBLE);
            return;
        }
        iv_original.setVisibility(View.VISIBLE);
        tv_original.setVisibility(View.VISIBLE);
        if (!MultiMediaController.isOriginal) {
            iv_original.setBackgroundResource(R.drawable.picker_check_disable);
            iv_original.setImageDrawable(null);
            tv_original.setText(context.getResources().getString(R.string.picker_original));
        } else {
            iv_original.setBackgroundResource(R.drawable.picker_check_enable);
            iv_original.setImageResource(R.mipmap.picker_check);
            tv_original.setText(context.getResources().getString(R.string.picker_original) + MultiMediaController.getImageSize());
        }
    }

    private void setData(final boolean isShowCamera) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setCount();
                setOriginal();
                easyActionBar.setTitleText(imageBucketList.get(bucketIndex).bucketName);
                if (isShowCamera && imageBucketList.get(bucketIndex).multiMediaItemList.size() != 0 && !imageBucketList.get(bucketIndex).multiMediaItemList.get(0).path.equals(MultiMediaItem.CAMERA)) {
                    MultiMediaItem multiMediaItem = new MultiMediaItem();
                    multiMediaItem.path = MultiMediaItem.CAMERA;
                    multiMediaItem.mimeType = "image";
                    imageBucketList.get(bucketIndex).multiMediaItemList.add(0, multiMediaItem);
                }
                recyclerViewAdapter.setNewInstance(imageBucketList.get(bucketIndex).multiMediaItemList);
                if (dialog != null)
                    dialog.dismiss();
            }
        });
    }

    /**
     * 拍照
     */
    private void takePhotoByCamera() {
        System.gc();
        Glide.get(this).clearMemory();
        Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        ImageCacheUtils imageCacheUtils = new ImageCacheUtils(context);
        File file = new File(imageCacheUtils.getCachePath(), System.currentTimeMillis() + ".jpg");
        cameraPath = file.getPath();

        ContentValues contentValues = new ContentValues(1);
        contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
        Uri imageUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

        openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        startActivityForResult(openCameraIntent, RESULT_CAMERA);
    }

    /**
     * 录像
     */
    private void takeVideoByCamera() {
        System.gc();
        Glide.get(this).clearMemory();
        Intent openCameraIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        ImageCacheUtils imageCacheUtils = new ImageCacheUtils(context);
        File file = new File(imageCacheUtils.getCachePath(), System.currentTimeMillis() + ".mp4");
        cameraPath = file.getPath();

        ContentValues contentValues = new ContentValues(1);
        contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
        Uri imageUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

        openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        openCameraIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        openCameraIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, MultiMediaController.videoMaxDuration / 1000);
        openCameraIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, MultiMediaController.videoMaxSize);
        startActivityForResult(openCameraIntent, RESULT_VIDEO);
    }

    private static class RecyclerViewAdapter extends BaseQuickAdapter<MultiMediaItem, BaseViewHolder> implements LoadMoreModule {
        private Context context;
        private int cameraResourceId = 0;

        public RecyclerViewAdapter(Context context, @Nullable List<MultiMediaItem> data) {
            super(R.layout.picker_view_griditem, data);
            this.context = context;

            TypedValue typedValue = new TypedValue();
            context.getTheme().resolveAttribute(R.attr.picker_cameraRes, typedValue, true);
            cameraResourceId = typedValue.resourceId;
        }

        @SuppressLint("SetTextI18n")
        @Override
        protected void convert(@NotNull final BaseViewHolder viewHolder, final MultiMediaItem item) {
            final ImageView iv_img = viewHolder.getView(R.id.iv_img);
            if (item.path.equals(MultiMediaItem.CAMERA)) {
                viewHolder.setGone(R.id.tv_check, true);
                Glide.with(context).asBitmap().load(cameraResourceId).dontAnimate().into(iv_img);
            } else {
                if (item.mimeType.equals("image")) {
                    viewHolder.setGone(R.id.tv_check, false);
                    viewHolder.setGone(R.id.tv_duration, true);
                    if (item.suffix.equalsIgnoreCase("gif"))
                        viewHolder.setGone(R.id.tv_suffix, false);
                    else
                        viewHolder.setGone(R.id.tv_suffix, true);
                } else {
                    viewHolder.setGone(R.id.tv_check, true);
                    viewHolder.setGone(R.id.tv_duration, false);
                    viewHolder.setGone(R.id.tv_suffix, true);
                    viewHolder.setText(R.id.tv_duration, item.duration);
                }

                if (MultiMediaController.multiMediaItemMap.get(item.path) != null) {
                    viewHolder.setText(R.id.tv_check, MultiMediaController.multiMediaItemMap.get(item.path).index + "");
                    viewHolder.setBackgroundResource(R.id.tv_check, R.drawable.picker_check_enable);
                } else {
                    viewHolder.setText(R.id.tv_check, "");
                    viewHolder.setBackgroundResource(R.id.tv_check, R.drawable.picker_check_disable);
                }

                if (item.outHeight == 0 || item.outWidth == 0) {
                    viewHolder.setGone(R.id.iv_img, true);
                    viewHolder.setGone(R.id.tv_check, true);
                    viewHolder.setGone(R.id.tv_error, false);
                } else {
                    Glide.with(context).asBitmap().load(item.path).listener(new RequestListener<Bitmap>() {
                        @Override
                        public boolean onLoadFailed(@Nullable GlideException ex, Object model, Target<Bitmap> target, boolean isFirstResource) {
                            item.outHeight = 0;
                            item.outWidth = 0;
                            viewHolder.setGone(R.id.iv_img, true);
                            viewHolder.setGone(R.id.tv_check, true);
                            viewHolder.setGone(R.id.tv_error, false);
                            return true;
                        }

                        @Override
                        public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                            viewHolder.setGone(R.id.iv_img, false);
                            viewHolder.setGone(R.id.tv_check, false);
                            viewHolder.setGone(R.id.tv_error, true);
                            return false;
                        }
                    }).dontAnimate().into(iv_img);
                }
            }
        }
    }

    /**
     * 局部刷新
     */
    private void notifyDataSetChanged() {
        try {
            int currentPosition = ((RecyclerView.LayoutParams) recyclerView.getChildAt(0).getLayoutParams()).getViewAdapterPosition();
            for (int i = 0; i < 24; i++) {
                recyclerViewAdapter.notifyItemChanged(currentPosition + i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 更改状态栏颜色
     *
     * @param black 是否为黑色
     */
    private void changeStatusBarTextColor(boolean black) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
            if (black)
                getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);//设置状态栏黑色字体
            else
                getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);//恢复状态栏白色字体
        }
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            finishActivity();
        }
        return false;
    }

    private void finishActivity() {
        MultiMediaController.finish(context);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent paramIntent) {
        super.onActivityResult(requestCode, resultCode, paramIntent);
        if (resultCode == RESULT_OK) {
            if (requestCode == RESULT_TACK) {
                if (paramIntent == null || !paramIntent.getBooleanExtra("finish", false)) {
                    setCount();
                    setOriginal();
                    this.recyclerViewAdapter.notifyDataSetChanged();
                } else
                    MultiMediaController.getMultiMediaList(context);
            } else if (requestCode == RESULT_CAMERA) {
                MultiMediaController.addOrRemoveMultiMediaItem(context, cameraPath, "image");
                setCount();
                setOriginal();
            } else if (requestCode == RESULT_VIDEO) {
                MultiMediaController.addOrRemoveMultiMediaItem(context, cameraPath, "video");
                Intent intent;
                List<MultiMediaItem> multiMediaItemList = new ArrayList<>(MultiMediaController.multiMediaItemMap.values());
                intent = new Intent(context, VideoBrowseActivity.class);
                intent.putExtra("List", (Serializable) multiMediaItemList);
                startActivityForResult(intent, RESULT_TACK);
            } else if (requestCode == RESULT_CROP) {
                MultiMediaController.getMultiMediaList(context);
            }
        }
    }

    @Override
    protected void onDestroy() {
        recyclerViewAdapter = null;
        System.gc();
        Glide.get(this).clearMemory();
        super.onDestroy();
    }
}
